initial commit
[NEO FreeRunner Bike Holder] / bike_holder__.scad
1 $fn = 80;
2
3 HALFCUT = 0;    // cut it at all
4 CUT             = 1;    // side: left or right 0 / 1
5
6 // ----------- testing ---------------------
7 CUT_DIA = 0;    // diametrical cut (for testing)
8 FLATCUT = 0;    // 
9
10
11 HELPERS = false;
12 BODY    = 0;
13
14 // ---------- main settings ----------------
15
16 width   = 50;
17 height  = 100;
18 length  = 83;
19 angle   = 15;
20
21 lift    = 20;
22
23 neo_w   = 62; // 62
24 neo_h   = 120; // 120
25 neo_l   = 25; // 25
26
27 ERR             = 0.1;  // to remove thin junction walls
28
29 EXT             = 2;    // to extend inner caves & notches
30
31
32 // ---------- rounded rectangle ------------
33
34 module roundedBody( w, h, l, r ){
35         // r = 2;
36         w = w-r*2;
37         h = h-r*2;
38 //      translate([0, 0, 0]) 
39         hull() {
40                 cylinder( l, r, r );
41                 translate([0, w, 0]) cylinder( l, r, r );
42                 translate([h, 0, 0]) cylinder( l, r, r );
43                 translate([h, w, 0]) cylinder( l, r, r );
44         }
45 }
46
47 // color("blue") roundedBody( 20, 10, 10, 5 );
48
49 // ---------- pancake (4 light) -----------
50
51 module pancake(r1,h,r2){
52         translate([0, 0, r2]) minkowski(){
53                 cylinder(h-r2*2,r1-r2,r1-r2);
54                 sphere(r2);
55         }
56 }
57
58 // ---------- holder (vertical part) -------
59
60 M  = [[ 1,                      0,      0,      0   ],
61       [ 0,                      1,      0,      0   ],  
62       [ tan(angle), 0,  1,      0   ],
63       [ 0,                      0,      0,      1   ]] ;
64         
65 module verticalPart(){
66         
67         module glassNotch(){
68                 intersection(){
69                         translate([85,0,28]) color("red") pancake(22,22,9.9);
70                         difference(){
71                                 roundedBody( width-2, height-2, length, width/2 );
72                                 roundedBody( width-4, height-4, length, width/2 );
73                         }
74                 }
75         }
76                 
77         difference(){
78                 multmatrix(M) roundedBody( width, height, length, width/2 );
79                  
80                 translate([-40, (width+1)/2, -10 - lift]) rotate([90,0,0]) color("red") roundedBody( 60, 80, width+1, width/4 );
81                 
82                  // light front
83                   
84                 translate([85,0,28]) color("red") pancake(20,20,9.9);   
85                 translate([0,0,-1]) glassNotch();
86                  
87                 translate([51, 0, 31]) color("red") {
88                         translate([-2, 0, 4]) cube([27, 17 + 2 + EXT, 8], center=true);
89                         translate([4, 0, 5]) cube([15 + EXT, 17 + 2 + EXT, 10], center=true);
90
91                         translate([10, -EXT/2, 7]) rotate([0,90,0]) color("red") translate([0, -4, 0]) roundedBody( 12 + EXT, 6, 10, 2 );
92                         
93                         // button hole
94                         translate([1 - 2, 0, -20]) cylinder(20, 1.2 + EXT/2, 1.2 + EXT/2); 
95                         translate([1 - 2, 0, -5]) cylinder(6, 5+1, 5+1); 
96                 }
97                 
98                 translate([54, 0, -3]) color("red") sphere(20);
99                 
100                 // extra hidden hole 
101                 
102                 translate([35, -44, 31]) translate([0,30,0]) rotate([90,0,0]) cylinder( 18,3,3, center=true);
103                 
104                 // charger
105                 
106                 translate([35, 0, 25 + EXT/2]) color("red") cube([5 + EXT, 34 + EXT,23 + 1 + EXT], center=true); // charger
107                 translate([35 - EXT/2,-12 - EXT/2,6]) roundedBody( 12 + EXT/2, 7 + EXT/2, 10 + EXT, 3 ); // usb hole 
108                         
109                 // bolts 
110                 
111                 boltDia = 3.5;
112                 
113                 translate([15,0,79]) color("red") {
114                         translate([0,62/2,0]) rotate([90,0,0]) cylinder(62,boltDia/2,boltDia/2); // bolt 62mm                   
115                         translate([0,-width/2+3,0]) rotate([90,0,0]) cylinder(6,6,10);
116                         translate([0,width/2+3,0]) rotate([90,0,0]) cylinder(6,10,6);
117                 }
118                 
119                 translate([15,0,31]) color("red") {
120                         translate([0,62/2,0]) rotate([90,0,0]) cylinder(62,boltDia/2,boltDia/2); // bolt 62mm                   
121                         translate([0,-width/2+3,0]) rotate([90,0,0]) cylinder(6,6,10);
122                         translate([0,width/2+3,0]) rotate([90,0,0]) cylinder(6,10,6);
123                 }
124         }
125 }
126                         
127
128
129 // ---------- neo (horisontal part) --------
130
131 module neoHolder( w, h, l, thin ){
132         
133         MRad            = 10 - EXT;
134         BMRad           = 19;
135         roundPad        = 0.7;
136                 
137         difference(){
138                 translate([0, 0, BMRad/2])
139                 minkowski() { 
140                         roundedBody( w+thin*2 - BMRad, h+thin*2 - BMRad, l - BMRad, (w+thin*2 - BMRad)/2 );
141                         sphere(BMRad/2);
142                 }
143                 translate([-EXT/2, -EXT/2, thin + MRad/2 + ERR -1]) color("red") 
144                 minkowski() { 
145                         roundedBody( w-MRad + EXT, h-MRad + EXT, l-MRad, (w-MRad)/2 );
146                         sphere(MRad/2);
147                 }
148                 
149                 rotate([90, 0, 0]) translate([16 - EXT/2, 18-2, -50]) roundedBody(20,12 + EXT,100,3); // micro usb hole
150                 rotate([90, 0, 0]) translate([8, 20 - 1, 0]) cylinder(100,3/2,3/2); // button hole
151                 rotate([90, 0, 0]) translate([70 + 1,20,-40]) cylinder(20,3/2,3/2); // left button hole
152
153                 translate([-50,0.5,-10]) rotate([50, 0, 90])  roundedBody(25,5,50,3); // center safty hole
154                 
155                 translate([17,-27,13]) rotate([90, 0, 90]) roundedBody(18,20,4,6); // usb wire channel
156
157                 // soft pad
158                 
159                 translate([-roundPad - EXT/2, -roundPad - EXT/2, thin + 5]) color( "green" ) roundedBody( w+roundPad*2 + EXT, h+roundPad*2 + EXT, l * 0.28, w/2 );
160         }       
161 }
162
163
164
165 // ---------- soft connect -----------------
166
167 module softConnect( width, height, raduis ){ // inner size
168         
169         w = width + raduis*4;
170         h = height + raduis*4;
171         
172         module halfTorus(){
173                 difference(){
174                         rotate_extrude(convexity = 0) translate([w/2-raduis, 0, 0]) circle(raduis);
175                         color("green") translate([-w/2, 0, -raduis]) cube([w, w/2, raduis*2]);
176                 }
177         }
178         module roundedSubObject(){
179                 halfTorus();
180                 translate([0, h-w, 0]) rotate([0, 0, 180]) halfTorus();
181                 translate([w/2-raduis, -ERR/2, 0]) rotate([-90,0,0]) cylinder(h-w+ERR,raduis,raduis);
182                 translate([-(w/2-raduis), -ERR/2, 0]) rotate([-90,0,0]) cylinder(h-w+ERR,raduis,raduis);
183         }
184         difference(){
185                 rotate([0, 0, 90]) roundedBody( w-raduis*2, h-raduis*2, raduis, (w-raduis*2)/2 );
186                 roundedSubObject();
187         }
188
189 }
190
191 // ---------- handle bar -----------------
192
193 handleR         = 27/2; // diameter of vertical part of the 
194 handleR2        = 32/2; // 35/2 // diameter of horisontal part
195 handleAng       = 25; // 20
196
197
198 module handle(){
199         
200         horScale = 1.1;
201         
202         // vertical part
203         translate([0,0,-10]) scale([1, horScale, 1]) cylinder( 86, handleR, handleR); 
204         
205         // diagonal part
206         translate([95, 0, 83]) rotate([0, -90-handleAng, 0]) scale([1, horScale, 1]) linear_extrude(height=100, scale=[1.3,0.77], slices=20, twist=0) circle(handleR2);
207         
208         // wire aound the handle bar
209         color("red") intersection(){
210                 translate([88, 0, 80]) rotate([0, -90-handleAng, 0]) linear_extrude(height=100, scale=[1.4,0.9], slices=20, twist=0) scale([1, horScale, 1]) circle(handleR2);
211                 rotate([0, -90-handleAng+5, 0]) translate([0,0,-46]) cylinder(6,100,100);
212         }
213 }
214
215
216 // ---------- main part ------------------
217
218 module holder(){
219         verticalPart();
220         translate([0, 0, length]) multmatrix(M) rotate([0,0,-90]) softConnect( width, height, 8 );
221         translate([0, 0, length + 8 - ERR]) rotate([0, -angle, 0]) translate([-1,0,0]) neoHolder(neo_w, neo_h, neo_l, 10 );
222 }
223
224 module main() {
225         difference(){
226                 
227                 translate([0,0, 20 + lift ]) holder(); // main part
228                 translate([0,0,50]) handle(); // handle bar
229                 
230                 // under device holes
231
232                 translate([0,0,120+lift]) rotate([0, 90-angle, 0]) color("red") {
233                         translate([-2, -18+3 - EXT/2, 57]) rotate([0,90,0]) roundedBody(36 + EXT, 52 + EXT,14,3); // battery hole
234                         translate([-2, -18+10 - EXT/2, 10]) rotate([0,90,0]) roundedBody(36 + EXT, 37,8,10); // plug usb place
235                         translate([-6, -20, 12.5]) cube([20,20,6]); // plug usb channel
236                 }
237
238                 // wires path
239                 translate([34, 0, 77]) rotate([0, -handleAng + 5, 0]) color("red") translate([2,0,30]) cube([6,4,65], center=true);
240                         
241                 
242                 // vertical cutter
243                 
244                 if ( HALFCUT ) {
245                         if ( CUT ) 
246                                 translate([-neo_h/2,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); 
247                         else 
248                                 mirror([0,1,0]) translate([-neo_h/2,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); // vertical cutter
249                 }
250                 
251                 // perpendicular testing cutter
252                 
253                 if ( CUT_DIA ) {
254                         mirror([1,0,0]) translate([-neo_h/3,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); 
255                 }
256         }
257 }
258
259
260 if ( FLATCUT ) {
261 //      projection(cut=true) translate([0,0,0]) rotate([90,0,0]) // to make flat cut projection for SVG testing export
262         projection(cut=true) 
263         translate([0,0,-105]) // to make flat cut projection for SVG testing export
264         main();
265 } else {
266         main();
267 }
268
269 // ---------- control mesurement ----------
270
271 // neo dummy module
272 module neoDummy(){
273                 rad = 5;
274                 outerRad = 26;
275                 translate([rad,rad,rad]) color("purple") minkowski() { 
276                         translate([outerRad,outerRad,0]) roundedBody(62-rad*2, 120-rad*2, 19-rad*2, outerRad );
277                         sphere(rad);
278                 }
279                 translate([39,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2]) color("green") cylinder(100,1,1); // 39 button
280                 translate([50,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2-62/2]) color("green") cylinder(100,1,1); // 50 usb + jack
281                 translate([120-19,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2-62/2]) color("green") cylinder(100,1,1); // 19 from top, button left
282 }
283
284 if ( BODY ) translate([0, 0, 122 + lift]) rotate([0,-angle,0]) translate([-35,-31,0]) neoDummy() // neo dummy 
285
286 if ( HELPERS ) translate([10, -18+3, length + 36 + lift]) rotate([0, 90-angle, 0]) color("purple") roundedBody(35,10,50,3); // battery
287
288 if ( HELPERS ) translate([0, 0, 20]) {
289         translate([20, 0, 77]) rotate([0, -110, 0]) color("red") cube([36,1,1], center=true);
290         translate([0, 0, 100]) rotate([0, 90, 0]) color("red") cube([10,1,1], center=true);
291         translate([5, 0, 70]) rotate([0, 90, 0]) color("red") cube([70,1,1], center=true);
292         translate([-5, 0, 61]) rotate([0, 90, 0]) color("red") cube([88,1,1], center=true);
293         translate([0, 0, 16]) color("red") cylinder(19,39/2,35/2);
294         translate([0, 0, 6]) color("red") cylinder(10,50/2,50/2);
295         translate([45, 0, 100]) rotate([0, -18, 0]) color("red") cube([67,1,1], center=true);
296         
297         translate([0,62/2,0]) rotate([90,0,0]) color("red") cylinder(62,3/2,3/2); // bolt 62mm
298 }
Contact me: dev (at) shalnoff (dot) com
PGP fingerprint: A6B8 3B23 6013 F18A 0C71 198B 83D8 C64D 917A 5717